/*
 * Copyright 2014 Mario Guggenberger <mg@protyposis.net>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.example.mediaplayerdemo;


import net.protyposis.ohos.mediaplayer.MediaSource;
import net.protyposis.ohos.mediaplayer.UriSource;
import net.protyposis.ohos.mediaplayer.dash.AdaptationLogic;
import net.protyposis.ohos.mediaplayer.dash.DashSource;
import net.protyposis.ohos.mediaplayer.dash.SimpleRateBasedAdaptationLogic;
import ohos.app.Context;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.utils.net.Uri;

/**
 * Created by maguggen on 28.08.2014.
 */
public class Utils {

    private static final String TAG = Utils.class.getSimpleName();

    /**
     * uriToMediaSource
     * @param context context
     * @param uri uri
     * @return MediaSource
     */
    public static MediaSource uriToMediaSource(Context context, Uri uri) {
        MediaSource source = null;

        // A DASH source is either detected if the given URL has an .mpd extension or if the DASH
        // pseudo protocol has been prepended.
        if(uri.toString().endsWith(".mpd") || uri.toString().startsWith("dash://")) {
            AdaptationLogic adaptationLogic;

            // Strip dash:// pseudo protocol
            if(uri.toString().startsWith("dash://")) {
                uri = Uri.parse(uri.toString().substring(7));
            }

            //adaptationLogic = new ConstantPropertyBasedLogic(ConstantPropertyBasedLogic.Mode.HIGHEST_BITRATE);
            adaptationLogic = new SimpleRateBasedAdaptationLogic();

            source = new DashSource(context, uri, adaptationLogic);
        } else {
            source = new UriSource(context, uri);
        }
        return source;
    }

    /**
     * uriToMediaSourceAsync
     * @param context context
     * @param uri uri
     * @param callback callback
     */
    public static void uriToMediaSourceAsync(final Context context, Uri uri, MediaSourceAsyncCallbackHandler callback) {
        LoadMediaSourceAsyncTask loadingTask = new LoadMediaSourceAsyncTask(context, callback, uri);
        loadingTask.start();
    }

    private static class LoadMediaSourceAsyncTask extends Thread {

        private Context mContext;
        private MediaSourceAsyncCallbackHandler mCallbackHandler;
        private MediaSource mMediaSource;
        private Exception mException;
        private Uri mUri;

        private EventHandler handler;

        public LoadMediaSourceAsyncTask(Context context, MediaSourceAsyncCallbackHandler callbackHandler, Uri uri) {
            handler = new EventHandler(EventRunner.getMainEventRunner());

            mContext = context;
            mCallbackHandler = callbackHandler;
            mUri = uri;
        }

        @Override
        public void run() {
            super.run();
//            try {
                mMediaSource = Utils.uriToMediaSource(mContext, mUri);
//            } catch (Exception e) {
//                mException = e;
//            }

            handler.postTask(() -> {
                if(mException != null) {
                    mCallbackHandler.onException(mException);
                } else {
                    mCallbackHandler.onMediaSourceLoaded(mMediaSource);
                }
            });
        }
    }

    /**
     * MediaSourceAsyncCallbackHandler
     */
    public static interface MediaSourceAsyncCallbackHandler {
        /**
         * onMediaSourceLoaded
         * @param mediaSource mediaSource
         */
        void onMediaSourceLoaded(MediaSource mediaSource);

        /**
         * onException
         * @param e Exception
         */
        void onException(Exception e);
    }

    /**
     * Iterates a hierarchy of exceptions and combines their messages. Useful for compact
     * error representation to the user during debugging/development.
     * @param e e
     * @return String
     */
    public static String getExceptionMessageHistory(Throwable e) {
        String messages = "";

        String message = e.getMessage();
        if(message != null) {
            messages += message;
        }
        while((e = e.getCause()) != null) {
            message = e.getMessage();
            if(message != null) {
                messages += " <- " + message;
            }
        }

        return messages;
    }
}
